package com.quiz.file.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.quiz.common.config.QuizConfig;
import com.quiz.common.exception.ServiceException;
import com.quiz.common.mybatis.core.query.MPJLambdaWrapperPlus;
import com.quiz.common.mybatis.core.query.PlusWrappers;
import com.quiz.common.utils.file.FileUtils;
import com.quiz.file.domain.Bo.FileInfoBo;
import com.quiz.file.domain.model.FileInfo;
import com.quiz.file.domain.vo.FileInfoVo;
import com.quiz.file.mapper.FileMapper;
import com.quiz.file.service.IFileService;
import com.quiz.file.utils.FileConvertUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.jodconverter.DocumentConverter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 文件服务实现类
 *
 * @author ahuan
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class FileServiceImpl implements IFileService {

    private final FileMapper baseMapper;


    /**
     * 注入DocumentConverter（jodconverter内置）
     */
    private final DocumentConverter converter;


    /**
     * 保存上传文件信息
     *
     * @param bo 文件视图信息
     * @return {@link FileInfo}
     */
    @Override
    public Boolean sava(FileInfoBo bo) {
        FileInfo fileInfo = BeanUtil.copyProperties(bo, FileInfo.class);
        return baseMapper.insert(fileInfo) > 0;
    }

    @Override
    public List<FileInfo> savaBatch(List<FileInfoBo> bos) {
        List<FileInfo> fileInfo = BeanUtil.copyToList(bos, FileInfo.class);
        baseMapper.insertBatch(fileInfo);
        return fileInfo;
    }

    /**
     * 获取文件信息根据文件id
     *
     * @param id 文件id
     * @return {@link FileInfo}
     */
    @Override
    public FileInfo getFileById(Long id) {
        return baseMapper.selectOne(FileInfo::getFileId, id);
    }

    @Override
    public List<FileInfo> getFileByIds(Long[] ids) {
        return baseMapper.selectBatchIds(CollUtil.newArrayList(ids));
    }

    @Override
    public List<FileInfo> getFileByIds(long[] ids) {
        // 把long转为Long
        List<Long> longList = Arrays.stream(ids).boxed().collect(Collectors.toList());

        MPJLambdaWrapperPlus<FileInfo> wrapper = new MPJLambdaWrapperPlus<FileInfo>()
                .selectAll(FileInfo.class)
                .in(FileInfo::getFileId, longList);

        return baseMapper.selectList(wrapper);

    }

    @Override
    public boolean removeById(Long id) {
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    public void onlinePreview(Long fileId, HttpServletResponse response) throws Exception {
        FileInfo fileInfo = getFileById(fileId);
        File inputFile = new File(fileInfo.getFilePath());
        String newFileName = convertNameToPdf(fileInfo.getFileOriginName());
        File ouputFile = new File("D:/quiz/pdf/" + newFileName);
        if(!ouputFile.exists()){

        }
        ServletOutputStream outputStream = null;
        InputStream in = null;
        try {
            //文件转化
            FileUtils.setAttachmentResponseHeader(response, newFileName);
            response.setContentType("application/octet-stream");
            converter.convert(inputFile).to(ouputFile).execute();
            outputStream = response.getOutputStream();
            in = Files.newInputStream(ouputFile.toPath());
            IOUtils.copy(in, outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(outputStream);
        }

    }

    @Override
    public List<FileInfoVo> details(String fileIds) {
        String[] split = fileIds.split(",");
        List<FileInfo> fileInfos = baseMapper.selectBatchIds(Arrays.asList(split));
        List<FileInfoVo> fileInfoVos = BeanUtil.copyToList(fileInfos, FileInfoVo.class);
        fileInfoVos.forEach(fileInfoVo -> {
            fileInfoVo.setFileUrl(QuizConfig.getBaseUrl() + fileInfoVo.getFileUrl());
        });
        return fileInfoVos;
    }

    /**
     * 将文件名字转为pdf
     */
    private String convertNameToPdf(String fileName) throws Exception {
        int dotIndex = fileName.lastIndexOf(".");
        return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex) + ".pdf";
    }


    /**
     * 判断是否为 Office 文件（Word, Excel, PPT）
     */
    private boolean isOfficeFile(String extension) {
        return extension.equals("doc") || extension.equals("docx") ||
                extension.equals("xls") || extension.equals("xlsx") ||
                extension.equals("ppt") || extension.equals("pptx");
    }

    /**
     * 根据FileIds删除文件
     */
    @Override
    @Transactional
    public void deleteFileByFileIds(String fileIds) {
        try {
            List<Long> ids = Arrays.stream(fileIds.split(",")).mapToLong(Long::parseLong).boxed().collect(Collectors.toList());
            // 查询所有文件信息
            List<FileInfo> fileByIds = baseMapper.selectBatchIds(ids);

            // 删除物理文件 todo建立回收站机制
//            for (FileInfo fileInfo : fileByIds) {
//                File file = new File(fileInfo.getFilePath());
//                if (file.exists()) {
//                    if (!file.delete()) {
//                        log.error("文件删除失败，ID：{}，路径：{}", fileInfo.getFileId(), fileInfo.getFilePath());
//                        throw new ServiceException("物理文件删除失败");
//                    }
//                }
//            }


            // 删除数据库记录
             baseMapper.deleteBatchIds(ids);
        } catch (Exception e){
            log.error("文件删除异常，ID：{}", fileIds, e);
            throw new ServiceException("文件删除异常");
        }
    }


}
